package net.wwang.blog.service.impl;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.wf.captcha.*;
import com.wf.captcha.base.Captcha;
import io.jsonwebtoken.Claims;
import lombok.extern.slf4j.Slf4j;
import net.wwang.blog.commons.global.Constants;
import net.wwang.blog.commons.global.GlobalTipMsg;
import net.wwang.blog.dao.*;
import net.wwang.blog.pojo.*;
import net.wwang.blog.commons.global.ResponseResult;
import net.wwang.blog.pojo.bo.RefreshToken;
import net.wwang.blog.pojo.bo.UserAndRole;
import net.wwang.blog.service.UserService;
import net.wwang.blog.util.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.io.IOException;
import java.util.*;
import java.util.List;

/**
 * @author WangWei
 * @date 2020/8/14
 */
@Slf4j
@Service
@Transactional
public class UserServiceImpl implements UserService {
	private static final  String ACCOUNT_STATE_AVAILABLE = "1" ;
	@Autowired
	private IDGenerateUtil idGenerater;
	@Autowired
	private UserDao userDao;
	@Autowired
	private SettingDao settingDao;
	@Autowired
	private PasswordEncoderUtil passwordEncoder;
	@Autowired
	private RedisUtil redisUtil;
	@Autowired
	private Random random;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private TaskService taskService;
	@Autowired
	private RefreshTokenDao refreshTokenDao;
	@Autowired
	private UserRoleDao userRoleDao;
	public static final int[] captcha_front_types = {
			Captcha.FONT_1, Captcha.FONT_2, Captcha.FONT_3, Captcha.FONT_4,
			Captcha.FONT_5, Captcha.FONT_6, Captcha.FONT_7, Captcha.FONT_8,
			Captcha.FONT_9, Captcha.FONT_10
	};
	private static int[] captcha = {160, 60, 4, 3};

	/**
	 * 初始化管理员账户
	 *
	 * @param user
	 * @param request
	 * @return
	 */
	@Override
	public ResponseResult initManagerAccount(User user, HttpServletRequest request) {
		//查看是否已初始化
		Setting manageAccountState = settingDao.findOneByKey(Constants.Settings.MANAGER_ACCOUNT_INIT_STATE);
		if (manageAccountState != null) {
			log.info("Email has been initialized！");
			return ResponseResult.FAILED(GlobalTipMsg.HAS_INIT);
		}
		//校验数据
		if (Utils.isEmpty(user.getUsername())) {
			return ResponseResult.FAILED(GlobalTipMsg.USER_NAME_NOT_NULL);
		}
		if (Utils.isEmpty(user.getPassword())) {
			return ResponseResult.FAILED(GlobalTipMsg.PASSWORD_NOT_NULL);
		}
		if (Utils.isEmpty(user.getEmail())) {
			return ResponseResult.FAILED(GlobalTipMsg.EMAIL_NOT_NULL);
		}
		log.info("Account data verification completed！");
		// 设置数据
		String userId = String.valueOf(idGenerater.nextId());
		String roleId = String.valueOf(idGenerater.nextId());
		user.setId(userId);
		//设置角色信息
		Role role = new Role();
		role.setId(roleId);
		role.setRoleName(Constants.User.ROLE_ADMIN);
		log.info("Character information is set！");
		roleDao.save(role);
		UserAndRole user_And_role = new UserAndRole();
		user_And_role.setId(String.valueOf(idGenerater.nextId()));
		user_And_role.setUserId(userId);
		user_And_role.setRoleId(roleId);
		userRoleDao.save(user_And_role);

		user.setAvatar(Constants.User.DEFAULT_AVATAR);
		user.setSign(Constants.User.DEFAULT_STATE);
		user.setRegisterIp(Utils.getIpAddress(request));
		user.setLoginIp(Utils.getIpAddress(request));
		log.info("The initial IP address of the administrator is:" + Utils.getIpAddress(request));
		//”1“ 账户可用
		user.setState(ACCOUNT_STATE_AVAILABLE);
		//加密
		user.setPassword(passwordEncoder.encode(user.getPassword()));
		user.setRoles("");
		//保存到数据库
		userDao.save(user);
		//更新修改标记
		Setting setting = new Setting();
		setting.setId(String.valueOf(idGenerater.nextId()));
		setting.setKey(Constants.Settings.MANAGER_ACCOUNT_INIT_STATE);
		setting.setValue("1");
		settingDao.save(setting);
		log.info("The administrator account status is updated!");
		return ResponseResult.SUCCESS(GlobalTipMsg.INIT_SUCCESS);
	}

	/**
	 * 获取图灵验证码
	 *
	 * @param response
	 * @param captchaKey
	 * @throws IOException
	 * @throws FontFormatException
	 */
	@Override
	public void createCaptcha(HttpServletResponse response, String captchaKey) throws IOException, FontFormatException {
		long key = 0;
		if (Utils.isEmpty(captchaKey) || captchaKey.length() < 13) {
			return;
		}
		try {
			key = Long.parseLong(captchaKey);
		} catch (Exception e) {
			return;
		}
		// 设置请求头为输出图片类型
		response.setContentType("image/gif");
		response.setHeader("Pragma", "No-cache");
		response.setHeader("Cache-Control", "no-cache");
		response.setDateHeader("Expires", 0);
		int randomId = random.nextInt(5);
		switch (randomId) {
        /*  验证码存入session
          request.getSession().setAttribute("captcha", captcha1.text().toLowerCase());*/
			case 0:

				ArithmeticCaptcha captcha1 = new ArithmeticCaptcha(captcha[0],
						captcha[1]);
				captcha1.setFont(captcha_front_types[random.nextInt(2)]);
				captcha1.setCharType(Captcha.TYPE_NUM_AND_UPPER);
				captcha1.setLen(captcha[3]); // 几位数运算，默认是两位
				captcha1.getArithmeticString(); // 获取运算的公式：3+2=?
				outputImage(captcha1, response, key);

				break;

			case 1:

				SpecCaptcha captcha2 = new SpecCaptcha(captcha[0], captcha[1],
						captcha[2]);
				captcha2.setFont(captcha_front_types[random.nextInt(10)]);
				captcha2.setCharType(Captcha.TYPE_NUM_AND_UPPER);
				outputImage(captcha2, response, key);

				break;

			case 2:

				GifCaptcha captcha3 = new GifCaptcha(captcha[0], captcha[1],
						captcha[2]);
				captcha3.setFont(captcha_front_types[random.nextInt(10)]);
				captcha3.setCharType(Captcha.TYPE_NUM_AND_UPPER);
				outputImage(captcha3, response, key);

				break;

			case 3:

				// 中文类型
				ChineseCaptcha captcha4 = new ChineseCaptcha(captcha[0],
						captcha[1], captcha[2]);
				captcha4.setFont(new Font("楷体", Font.PLAIN, 28));
				outputImage(captcha4, response, key);

				break;

			case 4:

				ChineseGifCaptcha captcha5 = new ChineseGifCaptcha(captcha[0],
						captcha[1], captcha[2]);
				captcha5.setFont(new Font("楷体", Font.PLAIN, 28));
				outputImage(captcha5, response, key);

				break;
		}
	}

	/**
	 * 发送邮箱验证码
	 * 场景1：register 如果已经注册提示已被注册；
	 * 场景2：forget 如果没有注册过提示没有注册；
	 * 场景3：update 如果已经注册提示注册过。
	 *
	 * @param request
	 * @param emailAdress
	 * @return
	 */
	@Override
	public ResponseResult sendEmail(HttpServletRequest request, String emailAdress, String type) {
		//根据类型查询邮箱是否存在
		if (emailAdress == null) {
			return ResponseResult.FAILED(GlobalTipMsg.EMAIL_NOT_NULL);
		}
		if ("register".equals(type) || "update".equals(type)) {
			User userByEmail = userDao.findUserByEmail(emailAdress);
			if (userByEmail != null) {
				return ResponseResult.FAILED(GlobalTipMsg.EMAIL_ALREADY_REGISTER);
			}
		} else if ("forget".equals(type)) {
			User userByEmail = userDao.findUserByEmail(emailAdress);
			if (userByEmail == null) {
				return ResponseResult.FAILED(GlobalTipMsg.EMAIL_NEVER_REGISTER);
			}
		}

		//防止暴力发送：同一个邮箱，间隔60秒才能请求一次验证码，同一个IP最多只能发送10次，短信最多只能发送3次
		String ipAddress = Utils.getIpAddress(request);
		log.info("The user’s email address is located at:" + ipAddress);
		Integer ipSendTime = (Integer) redisUtil.get(Constants.User.KEY_EMAIL_SEND_IP + ipAddress);
		if (ipSendTime != null && ipSendTime > 10) {
			return ResponseResult.FAILED(GlobalTipMsg.IP_SEND_TOO_TIMES);
		}
		String addressSendTime = (String) redisUtil.get(Constants.User.KEY_EMAIL_SEND_ADRESS + emailAdress);
		if (addressSendTime != null) {
			return ResponseResult.FAILED(GlobalTipMsg.NOT_TOO_OFTEN);
		}
		//校验邮箱
		boolean isEmailFormat = Utils.checkEmail(emailAdress);
		if (!isEmailFormat) {
			return ResponseResult.FAILED(GlobalTipMsg.EMAIL_ADRESS_FORMAT_ERROR);
		}
		//6位随机验证码
		String verifyCode = String.valueOf(new Random().nextInt(899999) + 100000);
		log.info("Six-digit random email verification code:" + verifyCode);
		try {
			taskService.sendVrifyCode(verifyCode, emailAdress);
		} catch (Exception e) {
			return ResponseResult.FAILED(GlobalTipMsg.EMAIL_VERIFYCODE_SEND_FAILURE);
		}
		//记录到Redis
		if (ipSendTime == null) {
			ipSendTime = 0;
		}
		ipSendTime++;
		//保存到redis,单位是秒
		//验证码1个小时有效期
		redisUtil.set(Constants.User.KEY_EMAIL_SEND_IP + ipAddress, ipSendTime, 60 * 60);
		//发送1分钟一次
		redisUtil.set(Constants.User.KEY_EMAIL_SEND_ADRESS + emailAdress, "send", 60);
		//保存code,10分钟有效期,单位是毫秒
		redisUtil.set(Constants.User.KEY_EMAIL_CODE_CONTENT + emailAdress, verifyCode, 60 * 10);
		return ResponseResult.SUCCESS(GlobalTipMsg.VERIFYCODE_SEND_SUCCESS);
	}

	@Override
	public ResponseResult register(HttpServletRequest request, User user, String verifyCode, String captchaCode, String captchaKey) {
		//校验是否已经注册
		String username = user.getUsername();
		if (Utils.isEmpty(username)) {
			return ResponseResult.FAILED(GlobalTipMsg.USER_NAME_NOT_NULL);
		}
		User userByUsername = userDao.findUserByUsername(username);
		if (userByUsername != null) {
			return ResponseResult.FAILED(GlobalTipMsg.USER_ALREADY_REGISTER);
		}
		String email = user.getEmail();
		if (Utils.isEmpty(email)) {
			return ResponseResult.FAILED(GlobalTipMsg.EMAIL_NOT_NULL);
		}
		//检查邮箱格式
		if (!Utils.checkEmail(email)) {
			ResponseResult.FAILED(GlobalTipMsg.EMAIL_ADRESS_FORMAT_ERROR);
		}
		User userByEmail = userDao.findUserByEmail(email);
		if (userByEmail != null) {
			return ResponseResult.FAILED(GlobalTipMsg.EMAIL_ALREADY_REGISTER);
		}
		log.info("No problem with username status！");

		//检查邮箱验证码是否正确
		String emailVrifyCode = (String) redisUtil.get(Constants.User.KEY_EMAIL_CODE_CONTENT + email);
		if (Utils.isEmpty(emailVrifyCode)) {
			return ResponseResult.FAILED(GlobalTipMsg.VRIFYCODE_INVALID_OR_EXPIRED);
		}
		if (verifyCode.equals(emailVrifyCode)) {
			//移除redis的内容
			redisUtil.del(Constants.User.KEY_EMAIL_CODE_CONTENT + email);
		} else {
			return ResponseResult.FAILED(GlobalTipMsg.VRIFYCODE_ERROR);
		}

		//检查图灵验证码是否正确
		String captchaVrifyCode = (String) redisUtil.get(Constants.User.KEY_CAPTCHA_CONTENT + captchaKey);
		if (Utils.isEmpty(captchaVrifyCode)) {
			return ResponseResult.FAILED(GlobalTipMsg.CAPTCHA_INVALID_OR_EXPIRED);
		}
		if (captchaKey.equals(captchaVrifyCode)) {
			redisUtil.del(Constants.User.KEY_CAPTCHA_CONTENT + captchaKey);
		} else {
			ResponseResult.FAILED(GlobalTipMsg.CAPTCHA_VRIFYCODE_ERROR);
		}
		log.info("Verification code verified！");
		//密码加密
		String password = user.getPassword();
		if (Utils.isEmpty(password)) {
			return ResponseResult.FAILED(GlobalTipMsg.PASSWORD_NOT_NULL);
		}
		user.setPassword(passwordEncoder.encode(password));
		String userId = String.valueOf(idGenerater.nextId());
		String roleId = String.valueOf(idGenerater.nextId());
		//补全数据:ID IP 角色 头像 创建时间 状态
		user.setId(userId);
		String ipAddress = Utils.getIpAddress(request);
		user.setRegisterIp(ipAddress);
		user.setLoginIp(ipAddress);
		user.setState("1");
		user.setAvatar(Constants.User.DEFAULT_AVATAR);
		user.setSign(Constants.User.DEFAULT_STATE);
		//保存到数据库
		userDao.save(user);
		//设置角色信息
		Role role = new Role();
		role.setId(roleId);
		role.setRoleName(Constants.User.ROLE_GENERAL_USER);
		log.info("Character information is set！");
		roleDao.save(role);
		UserAndRole user_And_role = new UserAndRole();
		user_And_role.setId(String.valueOf(idGenerater.nextId()));
		user_And_role.setUserId(userId);
		user_And_role.setRoleId(roleId);
		userRoleDao.save(user_And_role);
		log.info("User registration information has been set!");
		//返回结果
		return ResponseResult.SUCCESS(GlobalTipMsg.REGISTER_SUCCESS).setData(user.getUsername());
	}

	@Override
	public ResponseResult login(String captcha, String captchaKey, User user, HttpServletRequest request, HttpServletResponse response) {
		//从redis里取出验证码进行校验
		String captchaVrifyCode = (String) redisUtil.get(Constants.User.KEY_CAPTCHA_CONTENT + captchaKey);
		if (Utils.isEmpty(captchaVrifyCode)) {
			return ResponseResult.FAILED(GlobalTipMsg.CAPTCHA_INVALID_OR_EXPIRED);
		}
		if (!captchaVrifyCode.equals(captcha.toUpperCase())) {
			return ResponseResult.FAILED(GlobalTipMsg.CAPTCHA_VRIFYCODE_ERROR);
		}
		//删除redis使用过的验证码
		redisUtil.del(Constants.User.KEY_CAPTCHA_CONTENT + captchaKey);
		//校验登录信息
		String username = user.getUsername();
		if (Utils.isEmpty(username)) {
			return ResponseResult.FAILED(GlobalTipMsg.USER_NAME_NOT_NULL);
		}
		String password = user.getPassword();
		if (Utils.isEmpty(password)) {
			return ResponseResult.FAILED(GlobalTipMsg.PASSWORD_NOT_NULL);
		}
		User userFromDb = userDao.findUserByUsername(username);
		if (userFromDb == null) {
			userFromDb = userDao.findUserByEmail(username);
		}
		if (userFromDb == null) {
			return ResponseResult.FAILED(GlobalTipMsg.USERNAME_OR_PWD_ERROR);
		}
		//用户存在
		boolean flag = passwordEncoder.matches(password, userFromDb.getPassword());
		if (!flag) {
			return ResponseResult.FAILED(GlobalTipMsg.USERNAME_OR_PWD_ERROR);
		}
		//密码正确
		//判断账号状态
		if (!"1".equals(userFromDb.getState())) {
			return ResponseResult.FAILED(GlobalTipMsg.ACCOUNT_DISABLED);
		}
		//动态配置权限
		List<String> ids = userRoleDao.findRoleIdsByUserId(userFromDb.getId());
		List<String> roles = roleDao.findRolesByUserIds(ids);
		String role = String.join(",", roles);

		log.info(role);
		if (Utils.isEmpty(role)) {
			return ResponseResult.FAILED("用户未配置任何角色，请检查！");
		}
		userFromDb.setRoles(role);
		createToken(response, userFromDb);
		return ResponseResult.SUCCESS(GlobalTipMsg.LOGIN_SUCCESS);
	}

	/**
	 * 通过携带的token_key检查用户是否登录
	 *
	 * @param request
	 * @param response
	 * @return
	 */
	@Override
	public User checkUserState(HttpServletRequest request, HttpServletResponse response) {
		String tokenKey = CookieUtil.getCookie(request, Constants.User.SYSTEM_COOKIE_TOKEN);
		log.info("tokenKey:" + tokenKey);
		User user = parseByTokenKey(tokenKey);
		if (user == null) {
			//查询refreshtoken
			RefreshToken refreshToken = refreshTokenDao.findRefreshTokenByTokenKey(tokenKey);
			if (refreshToken == null) {
				return null;
			}
			//存在，解析refreshtoken
			try {
				JwtUtil.parseJWT(refreshToken.getRefreshToken());
				String userId = refreshToken.getUserId();
				User userFromDb = userDao.findUserById(userId);
				List<String> ids = userRoleDao.findRoleIdsByUserId(userFromDb.getId());
				List<String> roles = roleDao.findRolesByUserIds(ids);
				String role = String.join(",", roles);
				userFromDb.setRoles(role);
				String newTokenKey = createToken(response, userFromDb);
				return parseByTokenKey(newTokenKey);
			} catch (Exception ex) {
				return null;
			}
		}
		return user;
	}

	@Override
	public ResponseResult getUserInfo(String userId) {
		//从数据库查询
		User user = userDao.findUserById(userId);
		if (user == null) {
			return ResponseResult.FAILED(GlobalTipMsg.USER_NOT_EXISTS);
		}
		//置空隐私数据（密码 邮箱IP）
		ObjectMapper mapper = new ObjectMapper();
		User newUser = null;
		try {
			newUser = mapper.readValue(mapper.writeValueAsString(user), User.class);
		} catch (JsonProcessingException e) {
			e.printStackTrace();
		}
		newUser.setPassword("");
		newUser.setEmail("");
		newUser.setLoginIp("");
		newUser.setRegisterIp("");
		return ResponseResult.SUCCESS().setData(newUser);
	}

	@Override
	public ResponseResult checkEmail(String email) {
		User userByEmail = userDao.findUserByEmail(email);
		return userByEmail == null ? ResponseResult.FAILED(GlobalTipMsg.EMAIL_NEVER_REGISTER) : ResponseResult.SUCCESS(GlobalTipMsg.EMAIL_ALREADY_REGISTER);
	}

	@Override
	public ResponseResult checkUsername(String username) {
		User userByUsername = userDao.findUserByUsername(username);
		return userByUsername == null ? ResponseResult.FAILED(GlobalTipMsg.USER_NOT_REGISTER) : ResponseResult.SUCCESS(GlobalTipMsg.USER_ALREADY_REGISTER);
	}

	/**
	 * 更新用户信息
	 *
	 * @param request
	 * @param response
	 * @param userId
	 * @param user
	 * @return
	 */
	@Override
	public ResponseResult updateUserInfo(HttpServletRequest request, HttpServletResponse response, String userId, User user) {
		User userFromKey = checkUserState(request, response);
		if (userFromKey == null) {
			return ResponseResult.UN_AUTHORIZED(GlobalTipMsg.ACCOUNT_NOT_LOGIN);
		}
		if (!userFromKey.getId().equals(userId)) {
			return ResponseResult.FAILED(GlobalTipMsg.NO_PERMISSION_TO_MODIFY);
		}
		User userAccount = userDao.findUserById(userId);
		//修改用户信息
		if (!Utils.isEmpty(user.getAvatar())) {
			userAccount.setAvatar(user.getAvatar());
		}
		userAccount.setSign(user.getSign());
		String username = user.getUsername();
		if (!Utils.isEmpty(username)) {
			User userByUsername = userDao.findUserByUsername(username);
			if (userByUsername != null) {
				return ResponseResult.FAILED(GlobalTipMsg.USER_ALREADY_REGISTER);
			}
			userAccount.setUsername(username);
		}
		userDao.save(userAccount);
		String tokenKey = CookieUtil.getCookie(request, Constants.User.SYSTEM_COOKIE_TOKEN);
		redisUtil.del(tokenKey);
		return ResponseResult.SUCCESS(GlobalTipMsg.USER_UPDATE_SUCCESS);
	}

	/**
	 * 删除修护，修改用户状态。
	 *
	 * @param request
	 * @param response
	 * @param userId
	 * @return
	 */
	@Override
	public ResponseResult deleteUser(HttpServletRequest request, HttpServletResponse response, String userId) {
		int result = userDao.deleteUserByState(userId);
		if (result > 0) {
			return ResponseResult.SUCCESS(GlobalTipMsg.DELETE_SUCCESS);
		}
		return ResponseResult.FAILED(GlobalTipMsg.USER_NAME_IS_NULL);
	}

	/**
	 * 获取用户列表（管理员操作）
	 *
	 * @param page
	 * @param size
	 * @param request
	 * @param response
	 * @return
	 */
	@Override
	public ResponseResult getUserList(int page, int size, HttpServletRequest request, HttpServletResponse response) {

		//获取用户列表
		if (page < Constants.Page.DEFAULT_PAGE) {
			page = Constants.Page.DEFAULT_PAGE;
		}
		if (size < Constants.Page.MIN_SIZE) {
			size = Constants.Page.MIN_SIZE;
		}
		Sort sort = Sort.by(Sort.Direction.DESC, "create_time");
		Pageable pageable = PageRequest.of(page - 1, size, sort);
		Page<User> all = userDao.getUserList(pageable);
		return ResponseResult.SUCCESS("获取用户列表成功.").setData(all);
	}

	/**
	 * 更新密码
	 *
	 * @param verifyCode
	 * @param user
	 * @return
	 */

	@Override
	public ResponseResult updateUserPassword(String verifyCode, User user) {
		//检查邮箱
		String emailAdress = user.getEmail();
		if (Utils.isEmpty(emailAdress)) {
			return ResponseResult.FAILED(GlobalTipMsg.EMAIL_NOT_NULL);
		}

		//根据邮箱去redis里拿验证码校验
		String redisVerifyCode = (String) redisUtil.get(Constants.User.KEY_EMAIL_CODE_CONTENT + emailAdress);
		if (redisVerifyCode == null || !redisVerifyCode.equals(verifyCode)) {
			return ResponseResult.FAILED(GlobalTipMsg.CAPTCHA_VRIFYCODE_ERROR);
		}
		redisUtil.del(Constants.User.KEY_EMAIL_CODE_CONTENT + emailAdress);
		//修改密码
		int result = userDao.updatePasswordByEmail(new PasswordEncoderUtil().encode(user.getPassword()), emailAdress);

		return result > 0 ? ResponseResult.SUCCESS("密码修改成功") : ResponseResult.FAILED("密码修改失败");
	}

	@Override
	public ResponseResult updateEmailAdress(String verifyCode, String email, HttpServletRequest request, HttpServletResponse response) {
		//检查登录状态
		User user = checkUserState(request, response);
		if (user == null) {
			return ResponseResult.FAILED(GlobalTipMsg.ACCOUNT_NOT_LOGIN);
		}
		//校验
		String emailVerifyCode = (String) redisUtil.get(Constants.User.KEY_EMAIL_CODE_CONTENT + email);
		if (Utils.isEmpty(emailVerifyCode)) {
			return ResponseResult.FAILED(GlobalTipMsg.VRIFYCODE_INVALID_OR_EXPIRED);
		}
		if (!emailVerifyCode.equals(verifyCode)) {
			return ResponseResult.FAILED(GlobalTipMsg.VRIFYCODE_ERROR);
		}
		//删除redis验证码
		redisUtil.del(Constants.User.KEY_EMAIL_CODE_CONTENT + email);
		//修改邮箱
		int result = userDao.updateEmailByUserId(email, user.getId());
		return result > 0 ? ResponseResult.SUCCESS("邮箱修改成功") : ResponseResult.FAILED("邮箱修改失败");
	}

	@Override
	public ResponseResult logout() {
		//校验登录状态
		String tokenKey = CookieUtil.getCookie(Utils.getRequest(), Constants.User.SYSTEM_COOKIE_TOKEN);
		if (Utils.isEmpty(tokenKey)) {
			return ResponseResult.FAILED(GlobalTipMsg.ACCOUNT_NOT_LOGIN);
		}
		//删除redis token
		redisUtil.del(Constants.User.KEY_TOKEN + tokenKey);
		//删除refresh token
		refreshTokenDao.deleteAllByTokenKey(tokenKey);
		//删除cookie
		CookieUtil.deleteCookie(Utils.getResponse(), Constants.User.SYSTEM_COOKIE_TOKEN);
		return ResponseResult.SUCCESS(GlobalTipMsg.LOGOUT_SUCCESS);
	}

	/**
	 * 创建新的token信息
	 *
	 * @param response
	 * @param userFromDb
	 * @return
	 */
	private String createToken(HttpServletResponse response, User userFromDb) {
		//删掉旧的数据
		refreshTokenDao.deleteAllByUserId(userFromDb.getId());
		//生成tocken
		Map<String, Object> claims = ClaimUtil.userToClaims(userFromDb);

		String token = JwtUtil.createToken(claims, Constants.TimeValue.TIME_TWO_HOUR);
		//tocken保存在redis中,返回唯一MD5值，前端携带MD5进行校验
		String tokenKey = Utils.getMd5Value(token);
		//保存token到redis有效期2小时
		redisUtil.set(Constants.User.KEY_TOKEN + tokenKey, token, Constants.TimeValue.TIME_TWO_HOUR);
		//token写入cookies
		CookieUtil.setCookie(response, Constants.User.SYSTEM_COOKIE_TOKEN, tokenKey);
		//生成刷新token
		String refreshTokenValue = JwtUtil.createRefreshToken(userFromDb.getId(), Constants.TimeValue.TIME_TOKEN_ONE_MOUNTH);
		RefreshToken refreshToken = new RefreshToken();
		refreshToken.setId(String.valueOf(idGenerater.nextId()));
		refreshToken.setRefreshToken(refreshTokenValue);
		refreshToken.setUserId(userFromDb.getId());
		refreshToken.setTokenKey(tokenKey);
		//保存到数据库
		refreshTokenDao.save(refreshToken);
		return tokenKey;
	}

	public void outputImage(Captcha captcha, HttpServletResponse response, long key) {
		log.info("图灵验证码：" + captcha.text());
		redisUtil.set(Constants.User.KEY_CAPTCHA_CONTENT + key,
				captcha.text(), 60 * 10);
		try {
			captcha.out(response.getOutputStream());
		} catch (IOException e) {
			log.error("验证码输出到页面异常！");
		}
	}

	private User parseByTokenKey(String tokenKey) {
		String token = (String) redisUtil.get(Constants.User.KEY_TOKEN + tokenKey);
		if (token != null) {
			try {
				Claims claims = JwtUtil.parseJWT(token);
				return ClaimUtil.claimsToUser(claims);
			} catch (Exception e) {
				log.info("TokenKey转换成User异常，" + tokenKey + " 已经过期");
				return null;
			}
		}
		return null;
	}
}
